/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

/**
 *
 * @author carlos
 */
import java.util.ArrayList;

public class FunctionsList {
    private ArrayList functions;
    private ArrayList<String> parameters;
    private ValuateList newList;
    
    /**
     * Constructor personalizado, instancia la clase
     * @param newList La lista a evaluar
     */
    public FunctionsList(ValuateList newList){
        this.newList = newList;
        functions = new ArrayList();
        parameters = new ArrayList<String>();
    }
    
    /**
     * @param function La cadena de la función ingresada por teclado
     */
    public void setFunctions(String function){
        ArrayList params = new ArrayList();
        String functionName;
        String functionBody;
        String functionParams;
        int paramsCounter = 0;
        int beginFunction;
        int endFunction;
        
        // Obtener inicio y final de los parámetros
        beginFunction = function.lastIndexOf('(');
        endFunction = function.lastIndexOf(')');
        
        // Obtener nombre, parámetros y cuerpo de la función
        functionName = function.substring(0, beginFunction);
        functionParams = function.substring(beginFunction+1, endFunction);
        functionBody = function.substring(endFunction+1, function.length()-1);
        
        // Eliminar a las cadenas el espacio inicial y final
        functionName.trim();
        functionParams.trim();
        functionBody.toCharArray();
        
        // Contar la cantidad de parámetros dentro de la función
        for(int i = beginFunction+1; i != endFunction; i++){
            char value = function.charAt(i);
            // Aumentar contador
            if(value != ' '){
                paramsCounter++;
                params.add("" + value);
            }
        }
        
        // Crear la función y añadirla a la lista
        Functions newFunction = new Functions(paramsCounter, functionName, functionBody, params);
        functions.add(newFunction);
    }
    
    /**
     * 
     * @param function
     * @return 
     */
    public String valuateFunction(String function){
       ArrayList param = new ArrayList();
       String ret = null;
       String functionName;
       String params;
       String[] array;
       Functions func = null;
       Functions tempFunc;
       boolean exist;
       int beginParams;
       int endParams;
       
       // Obtener los índices de los paréntesis
       beginParams = function.lastIndexOf('(');
       endParams = function.lastIndexOf(')');
       
       // Obtener nombre y parámetros
       functionName = function.substring(0, beginParams);
       params = function.substring(beginParams, endParams);
       
       // Eliminar los espacios iniciales y finales
       functionName.trim();
       params.trim();
       
       // Convertir la cadena de parámetros en un arreglo
       array = params.split(" ");
       
       // Buscar si la función existe dentro de la lista de funciones
       exist = false;
       for (int i = 0; i != functions.size(); i++){
           tempFunc = (Functions)functions.get(i);
           
           if(functionName.compareTo(tempFunc.getFunctionName()) == 0){
               func = tempFunc;
               exist = true;
               break;
           }
       }
       
       // Verificar si la función existe dentro de la lista
       if(exist){
           param = func.getParameters();
           // Añadir los parámetros a la lista
           for(int i = 0; i != array.length; i++){
               parameters.add(array[i]);
           }
           
           // Verificar si tienen la misma cantidad de parámetros
           if(parameters.size() == func.getParametersNum()){
               for(int j = 0; j != parameters.size(); j++){
                   newList.setInMap((String)param.get(j), (String)parameters.get(j));
               }
           }
           
           // Devolver resultados
           ret = newList.getResult(func.getFunctionBody());
           newList.clear();
       }
       
       return ret;
    }
}
